#!/usr/bin/env python
# encoding: utf-8
import os, shutil
import sys

sys.path.insert(0, 'tools/ardupilotwaf/')

APPNAME = 'myapp'
VERSION = 'v1.0.0'

top = '.'
out = 'build'

MCU_NAME = 'STM32F427VI'
REMOTE_HOST = '192.168.8.190'

CROSS_COMPILER = 'arm-none-eabi-'
OBJCOPY = CROSS_COMPILER + 'objcopy'
OBJDUMP = CROSS_COMPILER + 'objdump'
SIZE    = CROSS_COMPILER + 'size'
GDB     = CROSS_COMPILER + 'gdb'

def options(opt):
    opt.load('gcc gas')
    opt.load('compiler_c')
    opt.load('compiler_cxx')
    
def configure(cfg):
    print('root configure')
    
#    cfg.env.TOOLCHAIN = 'x86_64-linux-gnu-'
#    cfg.env.TOOLCHAIN = 'arm-linux-gnueabihf-'
    cfg.env.TOOLCHAIN = 'arm-none-eabi-'
#    cfg.env.TOOLCHAIN = ''

    cfg.load('toolchain')
    
    cfg.env.ASFLAGS += ['-mcpu=cortex-m4',
                        '-mthumb',
                        '-Wl,--defsym=__main_stack_size__=0x800',
                        '-O0',
                        '-g',
                        '-ggdb3'
    ]
    
    cfg.env.CFLAGS += ['-mcpu=cortex-m4',
                       '-mthumb',
                       '-Wl,--defsym=__main_stack_size__=0x800',
                       '-std=gnu99',
                       '-Wall',
                       '-fdata-sections',
                       '-ffunction-sections',
                       '-O0',
                       '-g',
                       '-ggdb3'
    ]
    
    cfg.env.CXXFLAGS += ['-mcpu=cortex-m4',
                         '-mthumb',
                         '-Wl,--defsym=__main_stack_size__=0x800'
                         '-fno-rtti',
                         '-fno-exceptions',
                         '-fno-builtin',
                         '-Wall',
                         '-fdata-sections',
                         '-ffunction-sections',
                         '-O0',
                         '-g',
                         '-ggdb3'
    ] 
    
    current_directory = os.getcwd()
    cfg.env.LDFLAGS += ['-mcpu=cortex-m4',
                        '-mthumb',
                        '-Wl,--defsym=__main_stack_size__=0x800',
                        '-Wl,--gc-sections',
                        '-Wl,-Map=' + str(current_directory) +'/build/bin/' + APPNAME +'.map',
                        '-T' + str(current_directory) + '/ld.script',
                        '-specs=nano.specs',
                        '-specs=nosys.specs'
    ]
    
    cfg.recurse('libs')
    cfg.recurse('app')
    
    cfg.load('clang_compilation_database')
    
def pre_build(pre_build):
    deps_dir = 'build/deps'
    if os.path.exists(deps_dir):
        print "build/deps已经存在"
    else:
        print "build/deps不存在，正在新建build/deps ..."
        os.makedirs(deps_dir)
        if os.path.exists(deps_dir):
            print("build/deps创建成功")
        else:
            print("build/deps创建失败")
            
    lsts_dir = 'build/lsts'
    if os.path.exists(lsts_dir):
        print "build/lsts已经存在"
    else:
        print "build/lsts不存在，正在新建build/lsts ..."
        os.makedirs(lsts_dir)
        if os.path.exists(lsts_dir):
            print("build/lsts创建成功")
        else:
            print("build/lsts创建失败")
       
def build(bld):
    print('root build')
    bld.recurse('libs')
    bld.recurse('app')
    bld.add_pre_fun(pre_build)
    bld.add_post_fun(objcopy)
    bld.add_post_fun(bin2json)
    bld.add_post_fun(copylib)
    
def objcopy(obj):
    command_elf2bin = OBJCOPY + ' -O binary ' + out + '/bin/' + APPNAME + '.elf ' + out + '/bin/' + APPNAME + '.bin'
    command_elf2hex = OBJCOPY + ' -O ihex ' + out + '/bin/' + APPNAME + '.elf ' + out + '/bin/' + APPNAME + '.hex'
    command_elf2dmp = OBJDUMP + ' -x --syms ' + out + '/bin/' + APPNAME + '.elf > ' + out + '/bin/' + APPNAME + '.dmp'
    command_elf2lst = OBJDUMP + ' -S ' + out + '/bin/' + APPNAME + '.elf > ' + out + '/bin/' + APPNAME + '.list'
    command_size    = SIZE + ' -B ' + out + '/bin/' + APPNAME + '.elf'
    print('command_elf2bin = ' + command_elf2bin)
    print('command_elf2hex = ' + command_elf2hex)
    print('command_elf2dmp = ' + command_elf2dmp)
    print('command_elf2lst = ' + command_elf2lst)
    print('command_size = ' + command_size)
    os.system(command_elf2bin)
    os.system(command_elf2hex)
    os.system(command_elf2dmp)
    os.system(command_elf2lst)
    os.system(command_size)
    print('\r')
    
def copylib(copylib):
    command_copylib = './tools/copy_libraries/copy_libraries.sh'
    print('copylib完整命令: ' + command_copylib)
    copylib.exec_command(command_copylib)
    
def bin2json(jsn):
    command_bin2json = 'python ./tools/bin2json/bin2json.py ' + out + '/bin/' + APPNAME + '.bin'
    print('bin2json完整命令: ' + command_bin2json)
    os.system(command_bin2json)
    
def upload(up):
    command_upload = "python ./tools/uploader/uploader.py " + out + "/bin/" + APPNAME + ".apj"
    print('upload完整命令:' + command_upload)
    print('正在上传，请稍后...')
    os.system(command_upload)
    
def flash(flash):
    command_flash = 'JLinkExe -device '+ MCU_NAME +' -speed 1000 -if SWD -CommanderScript ./tools/flash/flash.jlink'
    print('flash完整命令: ' + command_flash)
    print('正在烧写，请稍后...')
    os.system(command_flash)
    
def reset(reset):
    command_reset = 'JLinkExe -device '+ MCU_NAME +' -speed 1000 -if SWD -CommanderScript ./tools/reset/reset.jlink'
    print('reset完整命令: ' + command_reset)
    print('正在复位，请稍后...')
    os.system(command_reset)    
    
def debug_jlink(debug_jlink):
    command_gdb_server = 'nohup JLinkGDBServer -if swd -device ' + MCU_NAME + ' -endian little -speed 1000 -port 2331 -swoport 2332 -telnetport 2333 -vd -ir -localhostonly 0 -singlerun -strict -timeout 0 &'
    command_gdb = GDB + " -iex 'target remote localhost:2331' -iex 'monitor reset' -iex 'monitor halt' -ex 'load' " + out + "/bin/" + APPNAME + ".elf"
    print('debug server命令: \r\n' + command_gdb_server)
    print('\r')
    print('debug gdb命令: \r\n' + command_gdb)
    print('\r')
    print('正在启动JLinkGDBServer....')
    os.system(command_gdb_server)
    print('\r')
    print('gdb正在连接JLinkGDBServer...')
    os.system(command_gdb)
    
def debug_local(debug_local):
    command_gdb_server = 'nohup gdbserver localhost:2331 ' + out + "/bin/" + APPNAME + ".elf &"
    command_gdb = "gdb -iex 'target remote localhost:2331' -iex 'break main' -iex 'continue' -iex '-'"
    print('debug server命令: \r\n' + command_gdb_server)
    print('\r')
    print('debug gdb命令: \r\n' + command_gdb)
    print('\r')
    print('正在启动gdbserver....')
    os.system(command_gdb_server)
    print('\r')
    print('gdb正在连接gdbserver...')
    os.system(command_gdb)
    
def debug_remote(debug_remote):
    command_copy_kill_shell = "scp ./tools/kill_shell/close_gdbserver_local.sh " + REMOTE_HOST + ":/home/user/close_gdbserver_local.sh"
    command_run_kill_shell = "ssh user@" + REMOTE_HOST + " /home/user/close_gdbserver_local.sh &"
    command_rmdir = "ssh user@" + REMOTE_HOST + " rm -rf /home/user/" + APPNAME
    command_mkdir = "ssh user@" + REMOTE_HOST + " mkdir -p /home/user/" + APPNAME
    command_scp = "scp " + out + "/bin/" + APPNAME + ".elf " + REMOTE_HOST + ":/home/user/" + APPNAME + "/" + APPNAME + ".elf"
    command_gdb_server = "nohup ssh user@" + REMOTE_HOST + " gdbserver localhost:2331 /home/user/" + APPNAME + "/" + APPNAME + ".elf &"
    command_gdb = GDB + " -iex 'target remote " + REMOTE_HOST + ":2331' -iex 'break main' -iex 'continue' -iex '-'"
    
    print('command_copy_kill_shell = ' + command_copy_kill_shell)
    print('command_run_kill_shell = ' + command_run_kill_shell)
    print('command_rmdir = ' + command_rmdir)
    print('command_mkdir = ' + command_mkdir)
    print('command_scp = ' + command_scp)
    print('debug server命令: \r\n' + command_gdb_server)
    print('\r')
    print('debug gdb命令: \r\n' + command_gdb)
    print('\r')
    
    os.system(command_copy_kill_shell)
    os.system(command_run_kill_shell)
    os.system(command_rmdir)
    os.system(command_mkdir)
    os.system(command_scp)
    print('正在启动gdbserver....')
    os.system(command_gdb_server)
    print('\r')
    print('gdb正在连接gdbserver...')
    os.system(command_gdb)
    
def distclean(distclean):
    if os.path.exists("build"):
        shutil.rmtree("build")

def help(help):
    print('./waf help      显示本帮助文档')
    print('./waf configure 配置')
    print('./waf build     编译')
    print('./waf objcopy   根据elf文件输出bin hex dmp list文件')
    print('./waf copylib   复制.a文件到build/lib')
    print('./waf bin2json  将bin格式固件转换成json格式')
    print('./waf upload    上传固件，需要匹配的px4 bootloader')
    print('./waf flash     直接通过jlink烧写程序')
    print('./waf reset     复位芯片')
    print('./waf debug_jlink     开启JLinkGDBServer并用gdb连接进行调试')
    print('./waf debug_local     开启x86PC本机gdbserver并用gdb连接进行调试')
    print('./waf debug_remote    开启x86远程gdbserver并用gdb连接进行调试')
